<?php
class FormData implements ArrayAccess{

	const FLOAT = 1;
	const DATE  = 2;
	const CPF  = 3;
	const CNPJ  = 4;
	const CEP  = 5;
	const PHONE  = 6;
	const DATETIME  = 7;
	const BOOLEAN = 8;
	const AR_RELATED = 9;
	const AR = 10;
	const PAPELTRABALHO = 11;
	const ONESPACE = 12;
	const NUMBER = 13;

	/*
	 * Usado para formatar os números recebidos da
	 * web e colocados nos objetos de negócio.
	 * Para receber estes números, não é usado este valor
	 * mas sim o da culture
	 */
	const DECIMAL_SEPARATOR = '.';

	var $array;
	var $culture;
	var $formatInfo;
	var $sfDateFormat;
	var $utf8_decode;

	function __construct($array,$utf8_decode = false) {
		$this->array = $array;
		$this->utf8_decode = $utf8_decode;
	}

	public function setCulture($culture) {
		$this->culture = $culture;
	}

	public function get($nome,$format = null) {
		if(!isset($this->array[$nome])) {
			trigger_error('O parâmetro '.$nome.' não foi enviado no array que inicializou o FormData');
		}
		elseif($this->array[$nome] === '') {
			return null;
		}
		else {
			switch($format) {
				case self::FLOAT:
					$ret = $this->getFloat($this->array[$nome]);
					break;
				case self::DATE:
					$ret = $this->getDate($this->array[$nome]);
					break;
				case self::DATETIME:
					$ret = $this->getDatetime($this->array[$nome]);
					break;
				case self::PAPELTRABALHO:
        		case self::CNPJ:
				case self::CPF:
				case self::PHONE:
				case self::CEP:
				case self::NUMBER:
					$ret = $this->getOnlyNumbers($this->array[$nome]);
					break;
        case self::ONESPACE:
          $ret = $this->getOneSpace($this->array[$nome]);
          break;
				case self::AR_RELATED:
					$ret = $this->getPositiveArrayItens($this->array[$nome]);
					break;
				case self::AR:
					$ret = $this->getArrayItens($this->array[$nome]);
					break;
				case null:
					$ret = $this->array[$nome];
					break;
				default:
					trigger_error('Formato não suportado');
			}
		}
		if($this->utf8_decode) {
			return utf8_decode($ret);
		}
		else {
			return $ret;
		}

	}

	private function getPositiveArrayItens($ar) {
		$newAr = array();
		foreach($ar as $key=>$value) {
			if($value) {
				$newAr[] = $key;
			}
		}
		return $newAr;
	}

	private function getArrayItens($ar) {
		$ret = array();
		if(is_array($ar)) {
			foreach($ar as $item) {
				if($item) {
					$ret[] = $item;
				}
			}
			return $ret;
		}
		else {
			return array();
		}
	}


	private function getFloat($valor) {
		$formatInfo = $this->getFormatInfo();
		$formatInfo->getDecimalSeparator();
		$valor = str_replace($formatInfo->getGroupSeparator(),'',$valor);
		return str_replace($formatInfo->getDecimalSeparator(),self::DECIMAL_SEPARATOR,$valor);
	}

	public function convertArFloat($arFloat) {
		$ret = array();
		$formatInfo = $this->getFormatInfo();
		$formatInfo->getDecimalSeparator();
		if ( count($arFloat ) ){
			foreach($arFloat as $k=>$v) {
				$v = str_replace($formatInfo->getGroupSeparator(),'',$v);
				$ret[$k] = str_replace($formatInfo->getDecimalSeparator(),self::DECIMAL_SEPARATOR,$v);
			}
		}
		return $ret;
	}

	public function getBoolean($nome,$trueValue,$falseValue) {
		if(
		isset($this->array[$nome]) && $this->array[$nome])
		{
			return $trueValue;
		}
		else 
		{
			return $falseValue;
		}
	}
	private function getDate($valor) {
		$sfDateFormat = $this->getSfDateFormat();
		return $sfDateFormat->format(
    		$valor,
            'i',
    		$sfDateFormat->getInputPattern('d')
		);
	}

	private function getDateTime($valor) {
		$sfDateFormat = $this->getSfDateFormat();
		return $sfDateFormat->format(
    		$valor,
            'yyyy-MM-dd HH:mm:ss',
            'dd/MM/yyyy HH:mm'
      );
	}

	private function getTime($valor) {
		$sfDateFormat = $this->getSfDateFormat();
		return $sfDateFormat->format(
    		$valor,
            'i',
    		$sfDateFormat->getInputPattern('d')
		);
	}

	private function getOnlyNumbers($valor) {
		return preg_replace('/[^0-9]/', '', $valor);
	}

	private function getOneSpace($valor)
	{
	  return preg_replace('/([\r\n])+/', '', $valor);
	}

	private function getFormatInfo() {
		if(!$this->formatInfo) {
			if(!isset($this->culture)) {
				trigger_error("Para usar formatação de números, deve ser configurada uma culture nesta classe.");
			}
			$this->formatInfo = sfNumberFormatInfo::getInstance($this->culture);
		}
		return $this->formatInfo;
	}

	private function getSfDateFormat() {
		if(!$this->sfDateFormat) {
			if(!isset($this->culture)) {
				trigger_error("Para usar formatação de datas, deve ser configurada uma culture nesta classee.");
			}
			$this->sfDateFormat = new sfDateFormat($this->culture);
		}
		return $this->sfDateFormat;
	}
	/*
	 * Check if an offset axists
	 *
	 * @param   mixed $offset
	 * @return  boolean Whether or not this object contains $offset
	 */
	public function offsetExists($offset)
	{
		return isset($this->array[$offset]);
	}

	public function has($offset) {
		return isset($this->array[$offset]);
	}

	/**
	 * An alias of get()
	 *
	 * @see     get, __get
	 * @param   mixed $offset
	 * @return  mixed
	 */
	public function offsetGet($offset)
	{
		return $this->get($offset);
	}

	/**
	 * Sets $offset to $value
	 *
	 * @see     set, __set
	 * @param   mixed $offset
	 * @param   mixed $value
	 * @return  void
	 */
	public function offsetSet($offset, $value)
	{
		$this->array[$offset] = $value;
	}

	/**
	 * Unset a given offset
	 *
	 * @see   set, offsetSet, __set
	 * @param mixed $offset
	 */
	public function offsetUnset($offset)
	{
		unset($this->array[$offset]);
	}
}